package com.umeox.ota.ui.activity;

import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

import com.abupdate.iot_libs.data.remote.VersionInfo;
import com.abupdate.iot_libs.engine.otaStatus.OtaStatus;
import com.abupdate.iot_libs.engine.otaStatus.OtaStatusMgr;
import com.abupdate.iot_libs.utils.SPFTool;
import com.abupdate.trace.Trace;
import com.umeox.moto.watch.themes.app.ThemeAppCompatActivity;
import com.umeox.moto.watch.themes.util.UToast;
import com.umeox.moto.watch.themes.widget.RunTextView;
import com.umeox.ota.R;
import com.umeox.ota.engine.FotaInitTask;
import com.umeox.ota.gloable.App;
import com.umeox.ota.interact.callback.IOtaOperationFailedInter;
import com.umeox.ota.mvvm.ViewModelFactory;
import com.umeox.ota.mvvm.viewModel.HomeViewModel;
import com.umeox.ota.mvvm.viewModel.MainViewModel;
import com.umeox.ota.service.OtaService;
import com.umeox.ota.ui.view.DownloadView;
import com.umeox.ota.utils.ActivityCollector;
import com.umeox.ota.utils.RxTime;

import java.text.SimpleDateFormat;
import java.util.Locale;

public class HomeActivity extends ThemeAppCompatActivity implements View.OnClickListener {
    public static final String TAG_DOWNLOAD = "1";
    public static final String TAG_DOWNLOAD_COMPLETE = "2";
    public static final String TAG_DOWNLOAD_PAUSE = "3";
    SimpleDateFormat mDateFormat;
    private ViewModelFactory mViewModelFactory;
    private HomeViewModel mViewModel;
    private static final String TAG = "HomeActivity";
    private TextView mUpdateTimeTv, mUpdateTipTv;
    private RunTextView mVersionTv;
    private View mCheckIv;
    private ImageView mIvState;

    private TextView mTvState;
    private TextView mTvPrecent;
    private ProgressBar mProgressBar;

    private OtaStatus otaStatusTemp = OtaStatus.IDLE;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        mDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
        ActivityCollector.addActivity(this, getClass());
        mViewModelFactory = ViewModelFactory.getInstance(this.getApplication());
        mViewModel = ViewModelProviders.of(this, mViewModelFactory).get(HomeViewModel.class);
        getLifecycle().addObserver(mViewModel);
        initView();
        initData();
    }

    private void initView() {
        mVersionTv = findViewById(R.id.tv_version);
        mUpdateTimeTv = findViewById(R.id.tv_update_time);
        mTvState = findViewById(R.id.tv_state);

        mUpdateTipTv = findViewById(R.id.tv_update_tip);
        mCheckIv = findViewById(R.id.iv_home_check);
        mIvState = findViewById(R.id.iv_state);
        mTvPrecent = findViewById(R.id.tv_download_precent);
        mProgressBar = findViewById(R.id.progress_bar);

        mCheckIv.setOnClickListener(this);

        mVersionTv.setText(Build.DISPLAY);
        mVersionTv.requestFocus();
        mVersionTv.post(() -> mVersionTv.setMarqueEnable(true));

        mTvPrecent.setVisibility(View.GONE);
        mProgressBar.setVisibility(View.GONE);

    }


    protected void initData() {

        mViewModel.versionName.observeForever(new Observer<String>() {
            @Override
            public void onChanged(String s) {
                mUpdateTimeTv.setText(mDateFormat.format(System.currentTimeMillis()));
                mVersionTv.setText(s);
            }
        });
        mViewModel.displayNewVersionInfo.observeForever(new Observer<VersionInfo>() {
            @Override
            public void onChanged(VersionInfo versionInfo) {

                mUpdateTipTv.setText(R.string.new_software_available);
                if (OtaStatusMgr.getInstance().isDownloadFinished()) {
                    mUpdateTipTv.setText(R.string.download_finish);
                    Trace.d(TAG, "refreshStatus() isDownloadFinished");
                    return;
                }
                mVersionTv.setText(versionInfo.versionAlias);
                mIvState.setImageResource(R.drawable.ic_download);
                mCheckIv.setTag(TAG_DOWNLOAD);
                mCheckIv.setBackgroundResource(R.drawable.navigationbar_bg);
            }
        });
        mViewModel.otaStatusMutableLiveData.observeForever(new Observer<OtaStatus>() {
            @Override
            public void onChanged(OtaStatus otaStatus) {
                setStatus(otaStatus);
            }
        });
        mViewModel.dlProgress.observeForever(new Observer<Integer>() {
            @Override
            public void onChanged(Integer integer) {
                mProgressBar.setProgress(integer);
                mTvPrecent.setText(String.format(Locale.ENGLISH, "%d%%", integer));
            }
        });
        mViewModel.setCallback(new IOtaOperationFailedInter() {
            @Override
            public void checkFailed(String errorMsg) {
                if (errorMsg.equals(getString(R.string.update_last_version))) {
                    mUpdateTipTv.setText(errorMsg);
                    mCheckIv.setVisibility(View.VISIBLE);
                    return;
                }
                UToast.showCustomToast(HomeActivity.this, errorMsg, Toast.LENGTH_LONG);
                Log.w(TAG, "checkFailed: " + errorMsg);
                mUpdateTipTv.setText(getString(R.string.last_update));
                mCheckIv.setVisibility(View.VISIBLE);
            }

            @Override
            public void downloadFailed(String errorMsg) {
                if (getString(R.string.download_mobile_network).equals(errorMsg)) {
                    return;
                }
                UToast.showCustomToast(HomeActivity.this, errorMsg, Toast.LENGTH_LONG);
                Log.w(TAG, "downloadFailed: " + errorMsg);
            }

            @Override
            public void updateFailed(String errorMsg) {
                UToast.showCustomToast(HomeActivity.this, errorMsg, Toast.LENGTH_LONG);
                Log.w(TAG, "updateFailed: " + errorMsg);
            }
        });


        if (mViewModel.fotaInitCompleted()) {
            mViewModel.initData();
        } else {

            RxTime.newInstance()
                    .setPeriod(500)
                    .setMinTime(1000)
                    .setTimeout(15 * 1000)
                    .setICondition(() -> null != mViewModel && mViewModel.fotaInitCompleted())
                    .enqueue(true, new RxTime.IEnqueueListener() {
                        @Override
                        public void onComplete() {
                            mViewModel.initData();
                        }

                        @Override
                        public void onTimeOut() {
                            Log.e(TAG, "onTimeOut: ");

                        }
                    });
        }

    }

    @Override
    protected void onResume() {
        super.onResume();
        if (SPFTool.getBoolean(MainViewModel.SP_IS_COPY_FILE, false)) {
            return;
        }
        if (mViewModel.fotaInitCompleted()) {
            mViewModel.initData();
        }
    }

    @Override
    protected void onDestroy() {
        ActivityCollector.removeActivity(this);

        if (mViewModel != null) {
            getLifecycle().removeObserver(mViewModel);
        }
        this.mViewModel = null;

        super.onDestroy();
    }

    @Override
    protected void onStop() {
        super.onStop();
        OtaService.startService(OtaService.ACTION_SHOW_NOTIFICATION, "");
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();

        if (id == R.id.iv_home_check) {
            if (v.getTag() == null) {
                mUpdateTipTv.setText(getString(R.string.update_checking));
                mViewModel.checkVersion();
            } else if (v.getTag() == TAG_DOWNLOAD) {
                mViewModel.download(false);
            } else if (v.getTag() == TAG_DOWNLOAD_PAUSE) {
                mViewModel.cancelDownload();
            } else if (v.getTag() == TAG_DOWNLOAD_COMPLETE) {
                mViewModel.upgrade();
            }
        }
    }

    @Override
    public void onBackPressed() {
        if (otaStatusTemp == OtaStatus.UPGRADING) {
            return;
        }

        super.onBackPressed();
    }


    public void setStatus(OtaStatus status) {
        Trace.d(TAG, "setStatus() :" + status);
        if (status == null) {
            return;
        }
        otaStatusTemp = status;
        switch (status) {
            case IDLE:
                refreshStatus(DownloadView.Status.STATE_QUERYNEWVERSION);
                break;
            case CHECKING:
                refreshStatus(DownloadView.Status.STATE_CHECKING);
                break;
            case UPGRADING:
                refreshStatus(DownloadView.Status.STATE_UPGRADING);
                break;
            case DOWNLOADING:
                refreshStatus(DownloadView.Status.STATE_DOWNLOADING);
                break;
            case UPGRADE_PAUSE:
            case DOWNLOAD_FINISHED:
                refreshStatus(DownloadView.Status.STATE_DLPKGCOMPLETE);
                break;
            case CHECK_NEW_VERSION:
                refreshStatus(DownloadView.Status.STATE_NEWVERSION_READY);
                break;
            case DOWNLOAD_PAUSE:
                refreshStatus(DownloadView.Status.STATE_PAUSEDOWNLOAD);
                break;
            case DOWNLOAD_FAILED:
                refreshStatus(DownloadView.Status.STATE_FAILEDDOWNLOAD);
                break;
            case UPGRADE_FAIL:
                refreshStatus(DownloadView.Status.STATE_FAILUPGRADE);
                break;
            case UPGRADE_SUCCESS:
                refreshStatus(DownloadView.Status.STATE_UPGRADE_SUCCESS);
                break;
            case NEED_REBOOT:
                refreshStatus(DownloadView.Status.STATE_NEED_REBOOT);
                break;

            default:
                break;
        }
    }


    public void refreshStatus(int status) {
        if (!FotaInitTask.isCompleted()) {
            Trace.d(TAG, "Init not completed");
            return;
        }
        switch (status) {
            case DownloadView.Status.STATE_QUERYNEWVERSION:
            case DownloadView.Status.STATE_FAILUPGRADE:
                Trace.d(TAG, "refreshStatus() STATE_QUERY_NEW_VERSION");
                // refreshView(View.VISIBLE, App.sCx.getString(R.string.update_last_version));
                break;

            case DownloadView.Status.STATE_CHECKING:
                // 检测版本中
                Trace.d(TAG, "refreshStatus() STATE_CHECKING");
                refreshView(View.INVISIBLE, App.sCx.getString(R.string.update_checking));
                break;

            case DownloadView.Status.STATE_NEWVERSION_READY:
                // 检测到新版本，可以点击下载
                Trace.d(TAG, "refreshStatus() STATE_NEW_VERSION_READY");
                mUpdateTimeTv.setVisibility(View.GONE);
                mCheckIv.setVisibility(View.VISIBLE);
                mCheckIv.setBackgroundResource(R.drawable.navigationbar_bg);
                mIvState.setImageResource(R.drawable.ic_download);
                break;
            case DownloadView.Status.STATE_CANCELDOWNLOAD:
                // 取消下载
                Trace.d(TAG, "refreshStatus() STATE_CANCEL_DOWNLOAD");
                break;

            case DownloadView.Status.STATE_DOWNLOADING:
                // 下载中，可以点击取消下载按钮
                Trace.d(TAG, "refreshStatus() STATE_DOWNLOADING");
                mUpdateTipTv.setText(R.string.downloading);
                mUpdateTimeTv.setVisibility(View.GONE);
                mProgressBar.setVisibility(View.VISIBLE);
                mTvPrecent.setVisibility(View.VISIBLE);
                mCheckIv.setVisibility(View.VISIBLE);
                mCheckIv.setBackgroundResource(R.drawable.navigationbar_bg);
                mIvState.setImageResource(R.drawable.ic_download_pause);
                mCheckIv.setTag(TAG_DOWNLOAD_PAUSE);
                break;

            case DownloadView.Status.STATE_DLPKGCOMPLETE:
                // 下载完成，可以点击升级
                Trace.d(TAG, "refreshStatus() STATE_DLPKG_COMPLETE");
                mUpdateTipTv.setText(R.string.download_finish);
                mProgressBar.setVisibility(View.VISIBLE);
                mProgressBar.setProgress(100);
                mTvPrecent.setVisibility(View.VISIBLE);
                mTvPrecent.setText("100%");
                mCheckIv.setVisibility(View.VISIBLE);
                mCheckIv.setBackgroundResource(R.drawable.navigationbar_bg);
                mIvState.setImageResource(R.drawable.ic_download);
                mIvState.setVisibility(View.GONE);
                mTvState.setText(R.string.download_install);
                mCheckIv.setTag(TAG_DOWNLOAD_COMPLETE);
                break;

            case DownloadView.Status.STATE_FAILEDDOWNLOAD:
                // 下载失败
                Trace.d(TAG, "refreshStatus() STATE_FAILED_DOWNLOAD");
                mProgressBar.setVisibility(View.GONE);
                mTvPrecent.setVisibility(View.GONE);
                mUpdateTipTv.setText(R.string.download_failed);
                mCheckIv.setBackgroundResource(R.drawable.navigationbar_bg);
                mIvState.setVisibility(View.GONE);
                mTvState.setText(R.string.download);
                mCheckIv.setTag(TAG_DOWNLOAD);
                break;

            case DownloadView.Status.STATE_PAUSEDOWNLOAD:
                // 显示暂停下载时的UI
                mCheckIv.setVisibility(View.VISIBLE);
                mCheckIv.setBackgroundResource(R.drawable.bg_btn_resume);
                mIvState.setImageResource(R.drawable.ic_download_start);
                mCheckIv.setTag(TAG_DOWNLOAD);
                break;

            case DownloadView.Status.STATE_UPGRADE:
            case DownloadView.Status.STATE_UPGRADING:
                // 升级中
                Trace.d(TAG, "refreshStatus() STATE_UPGRADE");
                break;
            case DownloadView.Status.STATE_UPGRADE_SUCCESS:
                Trace.d(TAG, "refreshStatus() STATE_UPGRADE_SUCCESS");
                break;
            case DownloadView.Status.STATE_NEED_REBOOT:
                Trace.d(TAG, "refreshStatus() STATE_NEED_REBOOT");
                MainActivity mainActivity = ActivityCollector.getActivity(MainActivity.class);
                if (mainActivity != null) {
                    mainActivity.createChooseAbupdateDialog();
                }
                break;
            default:
                break;
        }
    }

    public void refreshView(int checkVisibility, @Nullable String tips) {
        if (TextUtils.isEmpty(tips)) {
            mUpdateTipTv.setVisibility(View.GONE);
        } else {
            mUpdateTipTv.setVisibility(View.VISIBLE);
            mUpdateTipTv.setText(tips);
        }
        mCheckIv.setVisibility(checkVisibility);
    }

}
